#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include "udp.h"

void init_server(udp_server_t* serv, int port)
{
    
    struct sockaddr_in si_server;
    memset(&si_server, 0, sizeof (si_server));
    
    serv->ip = NULL;
    
    serv->s_ecoute = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    si_server.sin_family = AF_INET;
    
    si_server.sin_port = htons (port);
    
    si_server.sin_addr.s_addr = htonl(INADDR_ANY);
    
    bind (serv->s_ecoute, (struct sockaddr *) &si_server, sizeof si_server);
    
}

struct sockaddr_in init_sockaddr_in(char* ip, int port)
{
    struct sockaddr_in si_client;

    memset(&si_client, 0, sizeof (si_client));
    
    si_client.sin_family = AF_INET;
    
    si_client.sin_port = htons (port);
    
    si_client.sin_addr.s_addr = inet_addr (ip);
    
    return si_client;
}

int send_to_nonblock(udp_server_t* serv, struct sockaddr_in to, char* msg, int size)
{
    int r;
    
    if(size > SIZE_BUF)
    {
        exit(EXIT_FAILURE);
        perror("udp.c : send_to() : wrong param size");
    }
    
    
    r = (int)sendto (serv->s_ecoute, msg, size, MSG_DONTWAIT,
                        (struct sockaddr *) &to,
                        sizeof (to));
        
    return r;
}


int send_to(udp_server_t* serv, struct sockaddr_in to, char* msg, int size)
{
    int r;
    
    if(size > SIZE_BUF)
    {
        exit(EXIT_FAILURE);
        perror("udp.c : send_to() : wrong param size");
    }
    
    
    r = (int)sendto (serv->s_ecoute, msg, size, 0,
                     (struct sockaddr *) &to,
                     sizeof (to));
    
    return r;
}

int recv_from(udp_server_t* serv)
{
    struct sockaddr_in si_client;
    int size_si_client = sizeof (si_client);
    
    memset(&si_client, 0, sizeof (si_client));
    
    memset(serv->buf, 0, SIZE_BUF);
    
    serv->size = (int)recvfrom (serv->s_ecoute, serv->buf, (size_t)SIZE_BUF, 0,
                           (struct sockaddr *) &si_client,
                           (socklen_t *)&size_si_client);
    
    /* Reception problem */
    if(serv->size == 0)
    {
        return 0;
    }
    else if (serv->size == -1)
    {
        return -1;
    }
    
    
    serv->ip = inet_ntoa(si_client.sin_addr);
    
    
    return serv->size;
}

void close_server(udp_server_t* serv)
{
    close(serv->s_ecoute);
}





